//-------------------------------------------------------------------------------------
// <copyright file="SendPortGroup.cs" company="Microsoft">
//      Copyright (c) 2003 Microsoft Corporation. All rights reserved.
//      THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 
//      EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED 
//      WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
// </copyright>
// <summary>
//      A group of send ports.
// </summary>  
//-------------------------------------------------------------------------------------

namespace Microsoft.Sdc.Tasks.BizTalk2004.Configuration
{
	#region Using directives

    using System;
    using System.Collections;
    using System.Xml;
    using System.Xml.Serialization;

	#endregion

    /// <summary>
    /// A group of send ports.
    /// </summary>
    internal class SendPortGroup : BizTalkConfigurableEntityBase
    {
		#region Member Variables

        private SendPortCollection sendPorts = new SendPortCollection();
		private FilterGroupCollection filterGroups = new FilterGroupCollection();
		private PortStatus status;

		#endregion

		#region Constructors

		/// <summary>
		/// Creates a new send port group.
		/// </summary>
		/// <param name="installation">
		/// The BizTalk installation that the send port group belongs to.
		/// </param>
        public SendPortGroup(BizTalkInstallation installation)
			: this(installation, null)
        {
        }

		/// <summary>
		/// Creates a new send port group.
		/// </summary>
		/// <param name="installation">
		/// The BizTalk installation that the send port group belongs to.
		/// </param>
		/// <param name="name">
		/// The name of the send port group.
		/// </param>
        public SendPortGroup(BizTalkInstallation installation, string name) 
			: base(installation, name)
        {
        }   
     
		#endregion

		#region Properties

		public FilterGroupCollection FilterGroups
		{
			get 
			{ 
				return this.filterGroups; 
			}
		}

		public SendPortCollection SendPorts
		{
			get 
			{ 
				return this.sendPorts; 
			}
		}


		/// <summary>
		/// Port Status
		/// </summary>
		public PortStatus Status
		{
			get { return this.status; }
			set { this.status = value;}
		}


		#endregion

		#region Static Methods

		/// <summary>
		/// Deletes a send port group.
		/// </summary>
		/// <param name="installation">
		/// The <see cref="Microsoft.Sdc.Tasks.BizTalk2004.Configuration.BizTalkInstallation"/> that the send port
		/// group belongs to.
		/// </param>
		/// <param name="name">
		/// The name of the send port group.
		/// </param>
		public static void Delete(BizTalkInstallation installation, string name)
		{
			//check inputs
			if (installation == null)
			{
				throw new ArgumentNullException("installation");
			}
			if (name == null || name.Length == 0)
			{
				throw new ArgumentNullException("name");
			}

			//delete the send port group
			try
			{
				BtsSendPortGroup group = installation.CatalogExplorer.SendPortGroups[name];
				group.Status = PortStatus.Bound;	//must unenlist the port before deleting
				installation.CatalogExplorer.RemoveSendPortGroup(group);
				installation.CatalogExplorer.SaveChanges();
			}
			catch
			{
				installation.CatalogExplorer.DiscardChanges();
				throw;
			}
		}

		/// <summary>
		/// Loads the details of a send port group.
		/// </summary>
		/// <param name="installation">
		/// The <see cref="Microsoft.Sdc.Tasks.BizTalk2004.Configuration.BizTalkInstallation"/> that the send port
		/// group belongs to.
		/// </param>
		/// <param name="name">
		/// The name of the send port group.
		/// </param>
		/// <returns>
		/// A <see cref="Microsoft.Sdc.Tasks.BizTalk2004.Configuration.SendPortGroup"/>.
		/// </returns>
		public static SendPortGroup Load(BizTalkInstallation installation, string name)
		{
			//check inputs
			if (installation == null)
			{
				throw new ArgumentNullException("installation");
			}
			if (name == null || name.Length == 0)
			{
				throw new ArgumentNullException("name");
			}

			//load the actual group
			BtsSendPortGroup actualGroup = installation.CatalogExplorer.SendPortGroups[name];
			if (actualGroup == null)
			{
				throw new ArgumentException("The send port group does not exist.", "name");
			}

			//create the new config group and set its basic properties
			SendPortGroup configGroup = new SendPortGroup(installation, name);
			configGroup.status = actualGroup.Status;

			//load the send ports - make them point back to the existing ones in the installation object
			for (int i = 0; i < actualGroup.SendPorts.Count; i++)
			{
				BtsSendPort actualPort = (BtsSendPort)actualGroup.SendPorts[i];
				SendPort configPort = installation.SendPorts[actualPort.Name];
				configGroup.sendPorts.Add(configPort);
			}

			//load filter
			if (actualGroup.Filter != null && actualGroup.Filter.Length > 0)
			{
				configGroup.filterGroups.PopulateFromFilterXml(actualGroup.Filter);
			}

			//return the port group
			return configGroup;
		}

		/// <summary>
		/// Checks if the Send Port Group exists within BizTalk
		/// </summary>
		/// <param name="installation">
		/// The Microsoft.Sdc.Tasks.Configuration.BizTalk.Installation to search in.
		/// </param>
		/// <param name="name">
		/// The name of the Send Port Group
		/// </param>
		/// <returns>
		/// <b>true</b> if the Send Port Group exists, or <b>false</b> otherwise.
		/// </returns>
		public static bool Exists(BizTalkInstallation installation, string name)
		{
			return Exists(installation, CollectionType.SendPortGroup, name);
		}

		#endregion

		#region Methods

		/// <summary>
		/// Enlists the send port group.
		/// </summary>
		public void Enlist()
		{
			this.Installation.CatalogExplorer.SendPortGroups[this.Name].Status = PortStatus.Stopped;
			this.Installation.CatalogExplorer.SaveChanges();
		}

		/// <summary>
		/// Starts the send port group.
		/// </summary>
		public void Start()
		{
			this.Installation.CatalogExplorer.SendPortGroups[this.Name].Status = PortStatus.Started;
			this.Installation.CatalogExplorer.SaveChanges();
		}

		/// <summary>
		/// Stops the send port group.
		/// </summary>
		public void Stop()
		{
			this.Installation.CatalogExplorer.SendPortGroups[this.Name].Status = PortStatus.Stopped;
			this.Installation.CatalogExplorer.SaveChanges();
		}

		/// <summary>
		/// Unenlists the send port group.
		/// </summary>
		public void UnEnlist()
		{
			this.Installation.CatalogExplorer.SendPortGroups[this.Name].Status = PortStatus.Bound;
			this.Installation.CatalogExplorer.SaveChanges();
		}

        /// <summary>
        /// Saves the configuration of this send port group.
        /// </summary>
		protected internal override void SaveImpl()
		{
			BtsSendPortGroup actualGroup = this.Installation.CatalogExplorer.SendPortGroups[this.Name];
			if (actualGroup == null)
			{
				//group does not already exist so create it
				actualGroup = this.Installation.CatalogExplorer.AddNewSendPortGroup();
				actualGroup.Name = this.Name;
			}
			//save filter
			actualGroup.Filter = this.filterGroups.ToFilterXml();

			//remove any send ports from the group which have been removed
			for (int i = actualGroup.SendPorts.Count - 1; i >= 0; i--)
			{
				BtsSendPort actualPort = (BtsSendPort)actualGroup.SendPorts[i];
				if (!this.sendPorts.Contains(actualPort.Name))
				{
					actualGroup.SendPorts.Remove(actualPort.actualBtsObject);
				}
			}

			//add any send ports to the group which have been added
			foreach (SendPort configPort in this.sendPorts)
			{
				BtsSendPort actualPort = this.Installation.CatalogExplorer.SendPorts[configPort.Name];
				if (!actualGroup.SendPorts.Contains(actualPort))
				{
					actualGroup.SendPorts.Add(actualPort.actualBtsObject);
				}
			}
		}

		#endregion
	}
}

